﻿using System;
using System.Collections.Generic;

namespace Net.Formats.oEmbed
{
    /// <summary>
    /// Factory class, used to create 
    /// concrete oEmbed response types 
    /// depending on oEmbed response's "Type" value
    /// </summary>
    public class ResponseFactory
    {
        #region Class constructor

        ResponseFactory( ) { }

        #endregion

        /// <summary>
        /// Create oEmbed response type using parsed parameters
        /// returned from oEmbed provider
        /// </summary>
        /// <param name="responseParams">
        /// Collection of parsed key/value parameters
        /// returned by oEmbed resource provider
        /// </param>
        /// <returns>oEmbed response of a certain type according to its "Type" value</returns>
        public static GenericResponse Create( IDictionary<string, object> responseParams )
        {
            GenericResponse response = null;
            switch ( responseParams["type"].ToString() )
            {
                case "photo":
                    response = Create<PhotoResponse>( responseParams );                    
                    break;
                case "video":
                    response = Create<VideoResponse>( responseParams );                   
                    break;
                case "link":
                    response = Create<LinkResponse>( responseParams );
                    break;
                case "rich":
                    response = Create<RichResponse>( responseParams );                    
                    break;
                default:
                    break;
            }
            return response;
        }

        /// <summary>
        /// Create oEmbed response type using parsed parameters
        /// returned from oEmbed provider
        /// </summary>
        /// <typeparam name="T">Expected type of the oEmbed response</typeparam>
        /// <param name="responseParams">
        /// Collection of parsed key/value parameters
        /// returned by oEmbed resource provider
        /// </param>
        /// <returns>oEmbed response of a certain type according to its "Type" value</returns>
        public static T Create<T>( IDictionary<string, object> responseParams ) where T : GenericResponse, new()
        {
            var response = new T( );
            if ( responseParams.ContainsKey( "version" ) )
                response.Version = responseParams["version"].ToString();

            if ( responseParams.ContainsKey( "author_name" ) )
                response.AuthorName = responseParams["author_name"].ToString();

            if ( responseParams.ContainsKey( "author_url" ) )
            {
                Uri authorUrl = null;
                if ( Uri.TryCreate( responseParams["author_url"].ToString(), UriKind.Absolute, out authorUrl ) )
                    response.AuthorUrl = authorUrl;
            }

            if ( responseParams.ContainsKey( "cache_age" ) )
            {
                int cacheAge = 0;
                if ( int.TryParse( responseParams["cache_age"].ToString(), out cacheAge ) )
                    response.CacheAge = cacheAge;
            }

            if ( responseParams.ContainsKey( "provider_name" ) )
                response.ProviderName = responseParams["provider_name"].ToString();

            if ( responseParams.ContainsKey( "provider_url" ) )
            {
                Uri providerUrl = null;
                if ( Uri.TryCreate( responseParams["provider_url"].ToString(), UriKind.Absolute, out providerUrl ) )
                    response.ProviderUrl = providerUrl;
            }

            if ( responseParams.ContainsKey( "thumbnail_height" ) )
            {
                int thumbnailHeight = 0;
                if ( int.TryParse( responseParams["thumbnail_height"].ToString(), out thumbnailHeight ) )
                    response.ThumbnailHeight = thumbnailHeight;
            }

            if ( responseParams.ContainsKey( "thumbnail_url" ) )
            {
                Uri thumbnailUrl = null;
                if ( Uri.TryCreate( responseParams["thumbnail_url"].ToString(), UriKind.Absolute, out thumbnailUrl ) )
                    response.ThumbnailUrl = thumbnailUrl;
            }

            if ( responseParams.ContainsKey( "thumbnail_width" ) )
            {
                int thumbnailWidth = 0;
                if ( int.TryParse( responseParams["thumbnail_width"].ToString(), out thumbnailWidth ) )
                    response.ThumbnailWidth = thumbnailWidth;
            }

            if ( responseParams.ContainsKey( "title" ) )
                response.Title = responseParams["title"].ToString();

            if ( response is PhotoResponse )
            {
                PhotoResponse resp = response as PhotoResponse;

                if ( responseParams.ContainsKey( "url" ) )
                {
                    Uri url;
                    if ( Uri.TryCreate( responseParams["url"].ToString(), UriKind.Absolute, out url ) )
                        resp.Url = url;
                }

                if ( responseParams.ContainsKey( "width" ) )
                {
                    int width = 0;
                    if ( int.TryParse( responseParams["width"].ToString(), out width ) )
                        resp.Width = width;
                }

                if ( responseParams.ContainsKey( "height" ) )
                {
                    int height = 0;
                    if ( int.TryParse( responseParams["height"].ToString(), out height ) )
                        resp.Height = height;
                }
            }

            if ( response is VideoResponse )
            {
                VideoResponse resp = response as VideoResponse;

                if ( responseParams.ContainsKey( "html" ) )
                    resp.Html = responseParams["html"].ToString();

                if ( responseParams.ContainsKey( "width" ) )
                {
                    int width = 0;
                    if ( int.TryParse( responseParams["width"].ToString(), out width ) )
                        resp.Width = width;
                }

                if ( responseParams.ContainsKey( "height" ) )
                {
                    int height = 0;
                    if ( int.TryParse( responseParams["height"].ToString(), out height ) )
                       resp.Height = height;
                }
            }

            if ( response is RichResponse )
            {
                var resp = response as RichResponse;

                if ( responseParams.ContainsKey( "html" ) )
                    resp.Html = responseParams["html"].ToString();

                if ( responseParams.ContainsKey( "width" ) )
                {
                    int width = 0;
                    if ( int.TryParse( responseParams["width"].ToString(), out width ) )
                        resp.Width = width;
                }

                if ( responseParams.ContainsKey( "height" ) )
                {
                    int height = 0;
                    if ( int.TryParse( responseParams["height"].ToString(), out height ) )
                        resp.Height = height;
                }
            }
            
            return response;
        }
    }
}
